#include "grpc_client.h"
#include <iostream>

namespace cpp_backend {
namespace framework {

GrpcClient::GrpcClient(const std::string& host, int port) {
    endpoint_ = host + ":" + std::to_string(port);
    
    // 创建gRPC通道（不安全模式）
    channel_ = grpc::CreateChannel(endpoint_, grpc::InsecureChannelCredentials());
    
    // 创建Stub
    stub_ = service_rpc::ServiceRPC::NewStub(channel_);
}

Response GrpcClient::call(const Request& request) {
    // 1. 转换请求
    service_rpc::ServiceRequest grpc_request = convert_to_grpc_request(request);
    
    // 2. 准备响应
    service_rpc::ServiceResponse grpc_response;
    
    // 3. 创建ClientContext
    grpc::ClientContext context;
    
    // 设置超时（5秒）
    std::chrono::system_clock::time_point deadline =
        std::chrono::system_clock::now() + std::chrono::seconds(5);
    context.set_deadline(deadline);
    
    // 4. 调用RPC
    grpc::Status status = stub_->Call(&context, grpc_request, &grpc_response);
    
    // 5. 检查状态
    if (!status.ok()) {
        std::cerr << "gRPC call failed: " << status.error_message() << std::endl;
        return Response::Error(
            ErrorCode::INTERNAL_ERROR,
            "gRPC call failed: " + status.error_message()
        );
    }
    
    // 6. 转换响应
    return convert_from_grpc_response(grpc_response);
}

bool GrpcClient::health_check() {
    service_rpc::HealthCheckRequest request;
    service_rpc::HealthCheckResponse response;
    grpc::ClientContext context;
    
    // 设置短超时（1秒）
    std::chrono::system_clock::time_point deadline =
        std::chrono::system_clock::now() + std::chrono::seconds(1);
    context.set_deadline(deadline);
    
    grpc::Status status = stub_->HealthCheck(&context, request, &response);
    
    return status.ok() && response.healthy();
}

service_rpc::ServiceRequest GrpcClient::convert_to_grpc_request(const Request& request) {
    service_rpc::ServiceRequest grpc_request;
    
    // 基本信息
    grpc_request.set_path(request.GetPath());
    grpc_request.set_method(request.GetMethod());
    
    // Headers
    for (const auto& [key, value] : request.GetHeaders()) {
        (*grpc_request.mutable_headers())[key] = value;
    }
    
    // Params
    for (const auto& [key, value] : request.GetParams()) {
        (*grpc_request.mutable_params())[key] = value;
    }
    
    // Body（JSON序列化）
    if (!request.GetBody().is_null()) {
        std::string body_str = request.GetBody().dump();
        grpc_request.set_body(body_str);
    }
    
    // 认证信息
    grpc_request.set_user_id(request.GetUserId());
    grpc_request.set_username(request.GetUserName());
    grpc_request.set_user_role(request.GetUserRole());
    
    // 元信息
    grpc_request.set_client_ip(request.GetClientIp());
    grpc_request.set_request_id(request.GetRequestId());
    grpc_request.set_timestamp(
        std::chrono::system_clock::now().time_since_epoch().count()
    );
    
    return grpc_request;
}

Response GrpcClient::convert_from_grpc_response(
    const service_rpc::ServiceResponse& grpc_response
) {
    Response response;
    
    // HTTP状态码
    response.SetHttpStatus(static_cast<HttpStatus>(grpc_response.http_status()));
    
    // 业务错误码
    response.SetErrorCode(static_cast<ErrorCode>(grpc_response.error_code()));
    
    // 错误消息
    response.SetMessage(grpc_response.message());
    
    // Headers
    for (const auto& [key, value] : grpc_response.headers()) {
        response.SetHeader(key, value);
    }
    
    // Body（JSON反序列化）
    if (!grpc_response.body().empty()) {
        try {
            auto json_body = nlohmann::json::parse(grpc_response.body());
            response.SetData(json_body);
        } catch (const std::exception& e) {
            std::cerr << "Failed to parse response body: " << e.what() << std::endl;
        }
    }
    
    return response;
}

} // namespace framework
} // namespace cpp_backend
